package nobnak.study.gl.projection;

import android.opengl.Matrix;

public class MatrixMath {
	public static final float RADIUS_FROM_DEGREE = (float) (Math.PI / 180);
	public static final int VECTOR_DIMENSION = 4;
	public static final float HALF = 0.5f;

	public static void setIdentityMatrix(float[] matrix, int offset) {
		matrix[offset++] = 1f; matrix[offset++] = 0f; matrix[offset++] = 0f; matrix[offset++] = 0f;
		matrix[offset++] = 0f; matrix[offset++] = 1f; matrix[offset++] = 0f; matrix[offset++] = 0f;
		matrix[offset++] = 0f; matrix[offset++] = 0f; matrix[offset++] = 1f; matrix[offset++] = 0f;
		matrix[offset++] = 0f; matrix[offset++] = 0f; matrix[offset++] = 0f; matrix[offset++] = 1f;
	}
	public static void setTranslate(float[] matrix, int offset, float dx, float dy, float dz) {
		offset += 12;
		matrix[offset++] = dx;
		matrix[offset++] = dy;
		matrix[offset++] = dz;
	}
	public static void multiplyVector(float[] oVector, int offsetO, float[] matrix, int offsetM, float[] iVector, int offsetI) {
		for (int r = 0; r < VECTOR_DIMENSION; r++) {
			oVector[offsetO + r] = 
					  matrix[offsetM] * iVector[offsetI]
					+ matrix[offsetM + 1 * VECTOR_DIMENSION] * iVector[offsetI+1]
					+ matrix[offsetM + 2 * VECTOR_DIMENSION] * iVector[offsetI+2]
					+ matrix[offsetM + 3 * VECTOR_DIMENSION] * iVector[offsetI+3];
			offsetM++;
		}
	}
	public static void makePerspectiveMatrix(float[] matrix, int matrixOffset, float fovy, float aspect, float near, float far) {
		float deg = fovy * HALF * RADIUS_FROM_DEGREE;
		float t = near * (float) Math.sin(deg);
		float r = t * aspect;
		
		matrix[matrixOffset++] = near / r;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;

		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = near / t;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;

		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = (far + near) / (near - far);
		matrix[matrixOffset++] = -1f;

		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = (2 * far * near) / (near - far);
		matrix[matrixOffset++] = 0f;
	}
	public static void makeViewportMatrix(float[] matrix, int matrixOffset, int width, int height) {
		matrix[matrixOffset++] = width * HALF;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;

		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = - height * HALF;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;

		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 1f;
		matrix[matrixOffset++] = 0f;

		matrix[matrixOffset++] = width * HALF;
		matrix[matrixOffset++] = height * HALF;
		matrix[matrixOffset++] = 0f;
		matrix[matrixOffset++] = 1f;
	}
	public static void multiplyMatrix(float[] oMatrix, int offsetO, float[] matrixL, int offsetL, float[] matrixR, int offsetR) {
		Matrix.multiplyMM(oMatrix, offsetO, matrixL, offsetL, matrixR, offsetR);
	}
}
